package com.so206.controller.payment;

import com.github.pagehelper.PageInfo;
import com.so206.crond.process.SettPaymentThread;
import com.so206.plugins.pay.AliPayFunction;
import com.so206.plugins.pay.WxPayFunction;
import com.so206.po.*;
import com.so206.po.ext.SysSettExt;
import com.so206.service.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 结算控制
 */
@Controller
@RequestMapping("/admin/sett")
public class SettLementController {

    private static Logger logger = LoggerFactory.getLogger(SettLementController.class);


    @Autowired
    private SettLementService settLementService;

    @Autowired
    private UserService userService;

    @Autowired
    private AliPayFunction aliPayFunction;

    @Autowired
    private WxPayFunction wxPayFunctionPC;

    @Autowired
    private AlipayConfigService alipayConfigService;

    @Autowired
    private PayConfigService payConfigService;

    @Autowired
    private WxPayConfigService wxPayConfigService;

    @Autowired
    private WebConfigService webConfigService;

    /**
     * 结算列表
     */
    @RequiresPermissions("user_sett_list")
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "20") Integer rows,
                       @RequestParam(defaultValue = "false") Boolean ajax,
                       Model model, Integer status, HttpSession session, Integer payType, String sid) {
        SystemUser info = (SystemUser) session.getAttribute("userInfo");
        PageInfo<SysSettExt> bean = settLementService.findByPage(page, rows, status, sid, payType, info.getId());
        model.addAttribute("bean", bean);
        model.addAttribute("status", status);
        model.addAttribute("payType", payType);
        model.addAttribute("sid", sid);
        if (ajax) {
            return "admin/sett/list::pageNode";
        } else {
            return "admin/sett/list";
        }
    }

    /**
     * 结算列表 - 管理员
     */
    @RequiresPermissions("sys_sett_admin")
    @RequestMapping("/list_admin")
    public String list_admin(@RequestParam(defaultValue = "1") Integer page,
                             @RequestParam(defaultValue = "20") Integer rows,
                             @RequestParam(defaultValue = "false") Boolean ajax, Model model, Integer status, Integer payType, Long user, String sid) {
        PageInfo<SysSettExt> bean = settLementService.findByPage(page, rows, status, sid, payType, user);
        model.addAttribute("bean", bean);
        model.addAttribute("status", status);
        model.addAttribute("payType", payType);
        model.addAttribute("user", user);
        model.addAttribute("sid", sid);
        if (ajax) {
            return "admin/sett_admin/list::pageNode";
        } else {
            return "admin/sett_admin/list";
        }
    }

    /**
     * 查看结算
     */
    @RequiresPermissions("user_sett_list")
    @RequestMapping("/view")
    public String view(Long id, Model model) {
        SystemSett sett = settLementService.find_sett_byId(id);
        SystemUser user = userService.findUserById(sett.getUid());
        model.addAttribute("user2", user);
        model.addAttribute("model", sett);
        return "admin/sett/view";
    }

    /**
     * 查看结算 -  管理员
     */
    @RequiresPermissions("sys_sett_admin")
    @RequestMapping("/view_admin")
    public String view2(Long id, HttpSession session, Model model) {
        SystemUser info = (SystemUser) session.getAttribute("userInfo");
        SystemSett sett = settLementService.find_sett_byId(id);
        SystemUser user = userService.findUserById(sett.getUid());
        model.addAttribute("user2", user);
        model.addAttribute("model", sett);
        model.addAttribute("user", info);
        return "admin/sett_admin/view";
    }


    /**
     * 手动打款结算信息
     */
    @RequiresPermissions("sys_sett_admin")
    @RequestMapping("/update")
    @ResponseBody
    public Map update(Long id) throws Exception {
        HashMap<Object, Object> map = new HashMap<>();
        SystemPayConfig payConfig = payConfigService.getPayConfig(1L);
        SystemSett sett1 = settLementService.find_sett_byId(id);
        SystemUser user = userService.findUserById(sett1.getUid());
        Boolean money = false;
        if (user.getZspaytype() == 2) {//支付宝
            Long trAlipay = payConfig.getTrAlipay();
            AlipayConfig config_tr = alipayConfigService.find_by_id(trAlipay);
            money = aliPayFunction.changeMoneyToAccount(sett1, user, config_tr.getAppId(), config_tr.getPrivateKey(), config_tr.getPublicKey());
        } else if (user.getZspaytype() == 1) {//微信
            WxpayConfig by_id = wxPayConfigService.find_by_id(payConfig.getTrWxpay());
            money = wxPayFunctionPC.changeMoneyToWxAccount(sett1, user, by_id.getAppId(), by_id.getPid(), by_id.getPublicKeyMch(), by_id.getWxCert());
        } else if (user.getZspaytype() == 4) {
            WxpayConfig by_id = wxPayConfigService.find_by_id(payConfig.getTrWxpayCard());
            HashMap<String, String> param = new HashMap<>();
            param.put("str", UUID.randomUUID().toString().replaceAll("-", "").substring(0, 31));
            param.put("sid", sett1.getSid());
            param.put("pid", user.getZspayid());
            param.put("pname", user.getZsname());
            param.put("title", "转账:" + sett1.getSid());
            param.put("bank", user.getCardBankCode());
            param.put("final_money", String.valueOf(sett1.getSettFinalMoney()));
            Map ret = wxPayFunctionPC.payToUserCard(param, by_id.getAppId(), by_id.getPid(), by_id.getPublicKeyMch(), by_id.getWxCert());
            Object error = ret.get("error");
            Integer status = new Integer(ret.get("status").toString());
            Object tran_no = ret.get("tran_no");
            if (status == 2) {
                sett1.setStatus(2);
                sett1.setTranNo(String.valueOf(tran_no));
                sett1.setSettError(String.valueOf(error));
                money = true;
            } else {
                sett1.setStatus(3);
                sett1.setTranNo(String.valueOf(tran_no));
                sett1.setSettError(String.valueOf(error));
                money = false;
            }
        }
        if (money) {
            sett1.setStatus(2);
            sett1.setOkTime(new Date());
            map.put("code", 0);
            map.put("msg", "打款成功!");
        } else {
            sett1.setStatus(3);
            sett1.setOkTime(new Date());
            map.put("code", 0);
            map.put("msg", "打款失败!");
        }
        settLementService.updateSystemSett(sett1);
        return map;
    }

    /**
     * 删除结算信息
     */
    @RequestMapping("/delete")
    @RequiresPermissions("sys_sett_admin")
    @ResponseBody
    public Map delete(Long id) {
        HashMap<Object, Object> map = new HashMap<>();
        settLementService.deleteSystemSett(id);
        map.put("code", 0);
        map.put("msg", "删除成功!");
        return map;
    }

    /**
     * 设置打款状态
     */
    @RequiresPermissions("sys_sett_admin")
    @RequestMapping("/update2")
    @ResponseBody
    public Map update2(Long id, Integer type, HttpSession session) {
        SystemSett sett1 = settLementService.find_sett_byId(id);
        HashMap<Object, Object> map = new HashMap<>();
        sett1.setStatus(type);
        sett1.setTranNo("000");
        sett1.setSettError("000");
        sett1.setOkTime(new Date());
        settLementService.updateSystemSett(sett1);
        map.put("code", 0);
        map.put("msg", "设置成功!");
        return map;
    }

    /**
     * 立即批量打款
     */
    @RequiresPermissions("sys_sett_admin")
    @RequestMapping("/sett_now")
    @ResponseBody
    public Map re_sett() {
        HashMap<Object, Object> map = new HashMap<>();
        logger.info("当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        SettPaymentThread thread = new SettPaymentThread(settLementService, userService,
                aliPayFunction, wxPayFunctionPC, webConfigService, payConfigService,
                alipayConfigService, wxPayConfigService, 1);
        Thread model = new Thread(thread);
        model.setDaemon(true);
        model.start();
        map.put("msg", "批量打款请求已提交,系统正在处理中,请稍后刷新列表查看状态!");
        map.put("code", 0);
        return map;
    }

    /**
     * 导出数据
     */
    @RequiresPermissions("sys_sett_admin")
    @RequestMapping("/sett_export")
    @ResponseBody
    public void export(HttpServletResponse response) throws Exception {
        StringBuffer buffer = new StringBuffer();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        buffer.append("PID\t提现金额\t手续费\t打款金额\t提现方式\t提现账号\t姓名\t银行\t状态\t时间\r\n");
        List<SystemSett> sett = settLementService.findAllSett(1);
        for (SystemSett systemSett : sett) {
            SystemUser user = userService.findUserById(systemSett.getUid());
            buffer.append(systemSett.getUid() + "\t");
            buffer.append(systemSett.getSettPreMoney() + "\t");
            buffer.append(systemSett.getSettSubMoney() + "\t");
            buffer.append(systemSett.getSettFinalMoney() + "\t");
            if (systemSett.getPreType() == null) {
                buffer.append("用户未设置\t");
            } else {
                buffer.append(parsePrePayType(systemSett.getPreType()) + "\t");
            }
            if (user == null) {
                buffer.append("未找到用户\t");
                buffer.append("未找到用户\t");
            } else {
                if (user.getZspayid() == null) {
                    buffer.append("用户未设置\t");
                } else {
                    buffer.append(user.getZspayid() + "\t");
                }
                if (user.getZsname() == null) {
                    buffer.append("用户未设置\t");
                } else {
                    buffer.append(user.getZsname() + "\t");
                }
            }
            if (systemSett.getPreType() == null) {
                buffer.append("用户未设置\t");
            } else {
                if (systemSett.getPreType() == 4) {
                    buffer.append(getBankName(user.getCardBankCode()) + "\t");
                } else {
                    buffer.append("---\t");
                }
            }
            buffer.append("等待打款\t");
            buffer.append(sdf.format(systemSett.getCreateTime()));
            buffer.append("\r\n");
        }
        List<SystemSett> sett2 = settLementService.findAllSett(3);
        for (SystemSett systemSett : sett2) {
            SystemUser user = userService.findUserById(systemSett.getUid());
            buffer.append(systemSett.getUid() + "\t");
            buffer.append(systemSett.getSettPreMoney() + "\t");
            buffer.append(systemSett.getSettSubMoney() + "\t");
            buffer.append(systemSett.getSettFinalMoney() + "\t");
            if (systemSett.getPreType() == null) {
                buffer.append("用户未设置\t");
            } else {
                buffer.append(parsePrePayType(systemSett.getPreType()) + "\t");
            }
            if (user == null) {
                buffer.append("未找到用户\t");
                buffer.append("未找到用户\t");
            } else {
                if (user.getZspayid() == null) {
                    buffer.append("用户未设置\t");
                } else {
                    buffer.append(user.getZspayid() + "\t");
                }
                if (user.getZsname() == null) {
                    buffer.append("用户未设置\t");
                } else {
                    buffer.append(user.getZsname() + "\t");
                }
            }
            if (systemSett.getPreType() == null) {
                buffer.append("用户未设置\t");
            } else {
                if (systemSett.getPreType() == 4) {
                    buffer.append(getBankName(user.getCardBankCode()) + "\t");
                } else {
                    buffer.append("---\t");
                }
            }
            buffer.append("需要重新打款\t");
            buffer.append(sdf.format(systemSett.getCreateTime()));
            buffer.append("\r\n");
        }
        String sett_txt = buffer.toString();
        System.out.println(sett);
        response.setCharacterEncoding("utf8");
        response.setHeader("content-disposition",
                "attachment;filename=" +
                        URLEncoder.encode("sett_" + System.currentTimeMillis() + ".txt",
                                "UTF-8"));
        PrintWriter writer = response.getWriter();
        writer.write(sett_txt);
        writer.flush();
        writer.close();
    }

    /**
     * 解析提现方式
     */
    private static String parsePrePayType(Integer type) {
        switch (type) {
            case 1:
                return "微信";
            case 2:
                return "支付宝";
            case 3:
                return "QQ";
            case 4:
                return "银行卡";
            default:
                return "未知";
        }
    }

    /**
     * 根据银行代码获取银行名称
     */
    private static String getBankName(String code) {
        switch (code) {
            case "1002":
                return "工商银行";
            case "1005":
                return "农业银行";
            case "1026":
                return "中国银行";
            case "1003":
                return "建设银行";
            case "1001":
                return "招商银行";
            case "1066":
                return "邮储银行";
            case "1020":
                return "交通银行";
            case "1004":
                return "浦发银行";
            case "1006":
                return "民生银行";
            case "1009":
                return "兴业银行";
            case "1010":
                return "平安银行";
            case "1021":
                return "中信银行";
            case "1025":
                return "华夏银行";
            case "1027":
                return "广发银行";
            case "1022":
                return "光大银行";
            case "1032":
                return "北京银行";
            case "1056":
                return "宁波银行";
            case "":
                return "";
            default:
                return "错误";
        }
    }


    /**
     * 立即批量打款
     */
    @RequiresPermissions("sys_sett_admin")
    @RequestMapping("/sett_now2")
    @ResponseBody
    public Map re_sett2(Integer type) {
        HashMap<Object, Object> map = new HashMap<>();
        final Integer status = type;
        Thread thread = new Thread(() -> {
            List<SystemSett> sett = settLementService.findAllSett(1);
            for (SystemSett systemSett : sett) {
                systemSett.setStatus(status);
                systemSett.setTranNo("000");
                systemSett.setSettError("000");
                systemSett.setOkTime(new Date());
                settLementService.updateSystemSett(systemSett);
            }
            List<SystemSett> sett2 = settLementService.findAllSett(3);
            for (SystemSett systemSett : sett2) {
                systemSett.setStatus(status);
                systemSett.setTranNo("000");
                systemSett.setSettError("000");
                systemSett.setOkTime(new Date());
                settLementService.updateSystemSett(systemSett);
            }
        });
        thread.setDaemon(true);
        thread.start();
        map.put("msg", "批量处理请求已提交,系统正在处理中,请稍后刷新列表查看状态!");
        map.put("code", 0);
        return map;
    }
}
